home *** CD-ROM | disk | FTP | other *** search
- /*
-
- VID_CLOK.C - by Jerry Joplin [70441,2627] CIS
- This is a public domain demonstration of
- the vid_scrn library of fast video access
- functions.
-
- The .EXE file can be run as a very well behaved
- window under MicroSoft Windows(tm) or QuarterDeck's
- DESQview(tm). Set up a program information file
- for vid_clok.exe saying that the program does NOT
- directly modify the screen or any other memory.
-
- The provided version of the .EXE file was created by
- using a variant of the C0.ASM file provided with
- TURBOC(tm) compiler version 1.0 in order to get the
- memory the program needed down to the bare bones
- minimum. The .EXE file should run fine in window
- given 15k of memory.
-
- */
-
-
- #include <stdio.h>
- #include <dos.h>
- #include "vid_scrn.h"
-
- #define normal 0x07 /* Character attributes */
- #define reverse 0x70
-
- char hour;
- char min; /* Global clock variables to hold */
- char sec; /* the current time */
-
- struct {
- int value;
- int ypos;
- int xpos;
- } clock_dig[] = { /* The digital clock will contain */
- 10, 5, 3, /* four individual digits. This */
- 10, 5, 13, /* array holds structures of the */
- 10, 5, 27, /* digit's value and position */
- 10, 5, 37,
- } ;
-
-
- /******************************************************************************/
-
- main()
- {
- int i;
- register unsigned KeyStatus ;
- register unsigned LastStatus = 0;
-
- vid_clearbox(0,0,24,79,normal); /* Set up initial screen */
- vid_drawbox(0,0,19,48, normal, 1); /* Draw box around digits */
- show_left_shift(1,normal); /* Show initial shift status */
- show_right_shift(1,normal);
- vid_putc(' ',7,24,reverse); /* Make the 'colon' between hours */
- vid_putc(' ',13,24,reverse); /* and minutes and set the cursor */
- vid_poscurs(13,24); /* below it. Gives the colon a */
- /* blinking appearance in MS Windows*/
-
- /* Show instructions */
- vid_puts("Depress shift for seconds, or any other key to exit",21,0,normal);
-
- while (!kbhit()) { /* Main loop */
-
- getdostime(&hour,&min,&sec); /* Get system time */
- KeyStatus = keyflags() & 0x3; /* and shift key status */
-
- show_am_pm(); /* Indicate the AM or PM setting */
-
- if (KeyStatus) { /* If a shift key is down then.. */
-
- /* Check to see if the status of */
- /* the right shift has changed */
- if ( (KeyStatus & 0x1) != (LastStatus & 0x1) ) {
- if (KeyStatus & 0x1)
- show_right_shift(2,reverse);/* Show indicator if its pressed */
-
- else
- show_right_shift(1,normal); /* else right shift isn't pressed */
- }
-
- /* Check to see if the status of */
- /* the left shift has changed */
- if ( (KeyStatus & 0x2) != (LastStatus & 0x2) ) {
- if (KeyStatus & 0x2)
- show_left_shift(2,reverse); /* Show indicator for left shift */
- else
- show_left_shift(1,normal);
- }
-
-
- show_seconds(); /* Will always show seconds if */
- /* one of the shift keys is down */
- }
-
- else { /* If a shift key is not pressed */
-
- if (LastStatus & 0x1) { /* erase any shift key indicators */
- show_right_shift(1,normal); /* if we haven't already done so */
- }
- if (LastStatus & 0x2) {
- show_left_shift(1,normal);
- }
- show_time(); /* show the hours and minutes */
- }
- LastStatus = KeyStatus; /* Save this shift key status for */
- /* next check. */
- }
-
- getkey(); /* Get the keystroke that caused */
- /* kbhit to become positive */
-
- vid_poscurs(0,0); /* Set the cursor position */
- practice_window(); /* Show windowing technique */
- vid_clearbox(0,0,24,79,normal); /* and clear the screen at exit */
- }
-
-
- /******************************************************************************
- **
- ** Show the windowing potentials while giving a little plug for the author
- */
-
-
- practice_window()
- {
- register unsigned i;
- register char *buffptr;
- /* Allocate space to hold the */
- /* contents of video memory about */
- /* to be covered up */
- /******************************************************************************
- NOTE: commented out to avoid the call to malloc so we could use the bare bones
- minimum startup code. The savebuff is instead a static array.
-
- void *savebuff;
- if ( (savebuff=malloc(2400)) == NULL)
- return;
- *******************************************************************************/
- static char savebuff[2400];
-
-
- buffptr = savebuff; /* Prepare to save the contents */
- for (i = 0; i < 20; i++){ /* Save 20 rows */
- vid_memread((void *)buffptr,i,0,60); /* of 60 chars and attributes */
- buffptr += 120; /* increment buffer pointer by */
- /* character count * 2 */
- }
-
- vid_clearbox(0,0,19,59,normal); /* Start window with clean slate */
- vid_setbox(0,213,205,184,179,190,205,212,179);/* set a box rendition set */
- vid_drawbox(0,0,19,59,reverse,0); /* and draw the newly defined box */
-
- vid_puts(" Closing Window, hit any key to exit ",1,1,reverse);
- vid_puts("This digitial clock was a demonstration of a library" ,3,2,normal);
- vid_puts("of fast video screen access routines that are well" ,4,2,normal);
- vid_puts("behaved *just enough* to run in concurrently" ,5,2,normal);
- vid_puts("executing windowed tasks under control programs such as" ,6,2,normal);
- vid_puts("MicroSoft Windows (a registered trademark of MicroSoft)" ,7,2,normal);
- vid_puts("and DESQview. (a registered trademark of Quarterdeck)" ,8,2,normal);
- vid_puts("Please send any comments, improvements, enhancements," ,11,2,normal);
- vid_puts("or suggestions to:" ,12,2,normal);
- vid_puts(" Jerry Joplin [70441,2627] CIS" ,14,2,normal);
- vid_puts(" 3535 Plainsman Lane #F88" ,15,2,normal);
- vid_puts(" Bryan, TX 77802" ,16,2,normal);
-
- while (!getkey());
-
- buffptr = savebuff; /* Prepare to restore the covered */
- for (i = 0; i < 20; i++){ /* contents of video memory */
- vid_memwrite((void *)buffptr,i,0,60);/* Restore the 20 rows of */
- buffptr += 120; /* 60 chars and attributes */
- }
-
- for (i=0 ; i < 0xffff; i++) /* Briefly show the restore */
- ;
- }
-
-
-
- /******************************************************************************
- ** Show an indication that the Right shift key has been pressed
- */
-
- show_left_shift(boxset,attr)
- int boxset;
- int attr;
- {
- vid_drawbox(1,3,3,14,normal,boxset);
- vid_puts("Left Shift",2,4,attr);
- }
-
-
- /******************************************************************************
- ** Show an indication that the Right shift key has been pressed
- */
-
- show_right_shift(boxset,attr)
- int boxset;
- int attr;
- {
- vid_drawbox(1,29,3,41,normal,boxset);
- vid_puts("Right Shift",2,30,attr);
- }
-
-
- /******************************************************************************
- ** Show the current time in 12 hour am/pm format
- */
-
- show_time()
- {
- if (hour == 0 ) { /* if hour is 0 then set it */
- hour = 12; /* to 12 a.m. */
- }
- else if (hour > 12) { /* when hour is greater than 12 */
- hour -= 12; /* then substract 12 */
- }
-
- /* */
- /* There are four available digits on the screen clock , so set the two */
- /* left digits to the hour and the two right digits to the minute. */
- /* */
-
- clock_dig[1].value = hour % 10; /* Split the hour into 2 digits */
- hour /= 10;
- clock_dig[0].value = hour % 10;
-
- clock_dig[3].value = min % 10; /* Split the minute into 2 digits */
- min /= 10;
- clock_dig[2].value = min % 10;
-
- show_digits(); /* and display the digits */
- }
-
-
- /******************************************************************************
- ** Show the current minutes and seconds
- */
-
- show_seconds()
- {
- clock_dig[1].value = min % 10; /* Split the minute into 2 digits */
- min /= 10;
- clock_dig[0].value = min % 10;
-
- clock_dig[3].value = sec % 10; /* Split the second into 2 digits */
- sec /= 10;
- clock_dig[2].value = sec % 10;
-
- show_digits(); /* and display the digits */
- }
-
-
- /******************************************************************************
- ** Display the AM or PM indicator
- */
-
- static int pm_save = 2;
- static int pm = 0;
-
- show_am_pm()
- {
-
- if (hour > 11 ) /* Establish AM or PM setting */
- pm = 1;
- else
- pm = 0;
-
- if (pm_save != pm) { /* Check to see if the current */
- /* displayed value should change */
- pm_save = pm; /* If so then save this new value */
- if (pm) /* and display a P.M. */
- vid_puts("P.M.",18,2,normal); /* */
- else /* */
- vid_puts("A.M.",18,2,normal); /* or an AM depending on the hour */
- }
-
- /* */
- /* NOTE: pm_save is initially 2 so the first time through the AM/PM */
- /* indicator will be displayed since the pm flag can only be 0 or 1 */
- /* and the comparison of the pm flag to pm_save is what deterimes if */
- /* it should be displayed or not. */
- /* */
- }
-
-
-
- /******************************************************************************
- ** Define the clocks digits
- */
-
- struct digit_mask { /* The clocks digits are composed of 7 lines */
- unsigned top ; /* */
- unsigned upl ; /* top */
- unsigned upr ; /* ------ */
- unsigned mid ; /* | | */
- unsigned lowl ; /* upl | | upr */
- unsigned lowr ; /* | mid | */
- unsigned bot ; /* ------ */
- unsigned junk ; /* | | */
- } /* lowl | | lowr */
- /* | bot | */
- /* ------ */
- /* */
- /* Define the individual digits in an array */
- digit[] = { /* */
- { 1,1,1,0,1,1,1,0 }, /* 0 = top,upl,upr, lowl,lowr,bot */
- { 0,0,1,0,0,1,0,0 }, /* 1 = upr, lowr */
- { 1,0,1,1,1,0,1,0 }, /* 2 = top, ,upr,mid,lowl, bot */
- { 1,0,1,1,0,1,1,0 }, /* 3 = top, upr,mid, lowr,bot */
- { 0,1,1,1,0,1,0,0 }, /* 4 = upl,upr,mid, lowr */
- { 1,1,0,1,0,1,1,0 }, /* 5 = top,upl, mid, lowr,bot */
- { 1,1,0,1,1,1,1,0 }, /* 6 = top,upl, mid,lowl,lowr,bot */
- { 1,0,1,0,0,1,0,0 }, /* 7 = top, upr, lowr */
- { 1,1,1,1,1,1,1,0 }, /* 8 = top,upl,upr,mid,lowl,lowr,bot */
- { 1,1,1,1,0,1,0,0 }, /* 9 = top,upl,upr,mid, lowr */
- { 0,0,0,0,0,0,0,0 }, /* 10 = */
- }; /*NOTE: 10 is the special case of no lines */
-
- static int dsave[4][7] = {
- { 0,0,0,0,0,0,0 }, /* Array of last status for the individual lines */
- { 0,0,0,0,0,0,0 }, /* of the digits. It is undesirable to redisplay */
- { 0,0,0,0,0,0,0 }, /* the same item under MS Windows on an 8088 */
- { 0,0,0,0,0,0,0 }, /* or when several windows are active in DESQview*/
- } ;
-
- /******************************************************************************
- ** Display the clocks digits
- */
-
- show_digits()
- {
- register int i;
- register int j;
- int row,col,num;
-
- for ( i = 0; i < 4; i++) { /* Display the four digits */
-
- row = clock_dig[i].ypos; /* Get this digits starting row */
- col = clock_dig[i].xpos; /* column, */
- j = clock_dig[i].value; /* and current value */
-
- if ( i == 0 && j == 0 ) /* If the left most digit is zero */
- j = 10; /* then set it to empty digit(10) */
-
- /* Display the top line */
- if ( (num = digit[j].top) != dsave[i][0] ) { /* only if it has changed */
- dsave[i][0] = num; /* save the new value */
- horiz_bar(num, row, col+1);
- }
- /* Display the upper left line */
- if ( (num = digit[j].upl) != dsave[i][1] ) { /* only if it has changed */
- dsave[i][1] = num; /* save the new value */
- vertl_bar(num, row+1, col);
- }
-
- /* Display the upper right line */
- if ( (num = digit[j].upr) != dsave[i][2] ) { /* only if it has changed */
- dsave[i][2] = num; /* save the new value */
- vertl_bar(num, row+1, col+7);
- }
-
- /* Display the middle line */
- if ( (num = digit[j].mid) != dsave[i][3] ) { /* only if it has changed */
- dsave[i][3] = num; /* save the new value */
- horiz_bar(num, row+6, col+1);
- }
-
- /* Display the lower left line */
- if ( (num = digit[j].lowl) != dsave[i][4] ) {/* only if it has changed */
- dsave[i][4] = num; /* save the new value */
- vertl_bar(num,row+7, col);
- }
-
- /* Display the lower right line */
- if ( (num = digit[j].lowr) != dsave[i][5] ) {/* only if it has changed */
- dsave[i][5] = num; /* save the new value */
- vertl_bar(num,row+7, col+7);
- }
-
- /* Display the bottom line */
- if ( (num = digit[j].bot) != dsave[i][6] ) { /* only if it has changed */
- dsave[i][6] = num; /* save the new value */
- horiz_bar(num, row+12,col+1);
- }
- }
-
- /* */
- /* NOTE: dsave[][] is initially set to all zeros indicating the lines of */
- /* digits are all off. This way the first time through only what is needed*/
- /* to be displayed will be sent to the screen. */
- /* */
-
- }
-
-
-
- /******************************************************************************
- ** Draw or clear a horizonatal bar on the screen
- ** This uses VS_PUTS to display a string
- */
-
- static char *hbar = " "; /* Bar is a string of spaces */
-
- horiz_bar(turn_on,row,col)
- int turn_on,row,col;
- {
-
- if (turn_on) { /* If the bar should be turned */
- vid_puts(hbar,row,col,reverse); /* ON then use VS_PUTS to display */
- } /* the spaces in REVERSE video */
-
- else { /* If the bar should be turned */
- vid_puts(hbar,row,col,normal); /* OFF then use VS_PUTS to display */
- } /* the spaces in NORMAL video */
- }
-
- /******************************************************************************
- ** Draw or clear a vertical bar on the screen
- ** This uses VS_PUTC to display characters
- */
-
- static char vchar = ' ';
-
-
- vertl_bar(turn_on,row,col)
- int turn_on,row,col;
- {
- register unsigned vpos = row;
- register unsigned hpos = col;
-
- if (turn_on) { /* If the bar should be turned */
- for ( ; vpos < row + 5; vpos++) /* ON then use VS_PUTC to fill */
- vid_putc(vchar,vpos,hpos,reverse);/* the area with spaces in */
- } /* REVERSE video */
-
- else { /* If the bar should be turned */
- for ( ; vpos < row + 5; vpos++) /* OFF then use VS_PUTC to fill */
- vid_putc(vchar,vpos,hpos,normal); /* the area with spaces in */
- } /* NORMAL video */
- }
-
-
- /******************************************************************************/
-
- keyflags()
- {
- union REGS regs; /* Use function 1 of interrupt 16 */
- regs.h.ah = 0x2; /* to return the shift key state. */
- int86(0x16,®s,®s); /* It is interesting that Windows */
- return(regs.h.al); /* and DESQview return the actual */
- } /* shift state setting instead of */
- /* maintaining a separate process */
- /* shift status. */
- /******************************************************************************/
-
- getkey()
- {
- union REGS regs; /* Use function 0 of interrupt 16 */
- regs.h.ah = 0x0; /* to return keyboard input. */
- int86(0x16,®s,®s); /* Here DESQview and Windows */
- return(regs.h.al); /* intercept this call and return */
- } /* a keystroke for the calling */
- /* process. */
- /******************************************************************************/
-
- getdostime(hour,minute,second)
- char *hour;
- char *minute;
- char *second;
- {
- union REGS regs; /* Issue DOS function 2C to return */
- regs.h.ah = 0x2C; /* the system time. */
- int86(0x21,®s,®s);
- *hour = regs.h.ch;
- *minute = regs.h.cl; /* Store the returned value in the */
- *second = regs.h.dh; /* global clock setting variables */
- }
-
- /******************************************************************************/